package bcontractor.propositional.factories;

import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.CoreMatchers.not;
import static org.hamcrest.Matchers.greaterThan;
import static org.hamcrest.Matchers.greaterThanOrEqualTo;
import static org.hamcrest.Matchers.hasItem;
import static org.hamcrest.Matchers.lessThanOrEqualTo;
import static org.junit.Assert.assertThat;

import java.util.HashSet;
import java.util.Random;
import java.util.Set;

import org.junit.Before;
import org.junit.Test;

import bcontractor.propositional.PropositionalSentence;

/**
 * Tests an ArbitraryClauseFactory
 * 
 * @author lundberg
 * 
 */
public class ArbitraryClauseFactoryShould {

	private static final int samples = 100;

	private static final int minSize = 5;

	private static final int maxSize = 8;

	private static final int nVariables = 10;

	private SentenceFactory<PropositionalSentence> factory;

	@Before
	public void initialize() {
		Random random = new Random(31L);
		factory = new ArbitraryClauseFactory(random, nVariables, minSize, maxSize);
	}

	@Test
	public void shouldGenerateCorrectClauses() {
		for (int i = 0; i < samples; i++) {
			PropositionalSentence sentence = factory.create();
			assertThat(sentence.getClauses().length, is(1));
			int[] clause = sentence.getClauses()[0];
			assertThat(clause.length, is(greaterThanOrEqualTo(minSize)));
			assertThat(clause.length, is(lessThanOrEqualTo(maxSize)));
			Set<Integer> atoms = new HashSet<Integer>();
			for (Integer literal : clause) {
				Integer atom = Math.abs(literal);
				assertThat(atoms, not(hasItem(atom)));
				assertThat(atom, is(greaterThan(0)));
				assertThat(atom, is(lessThanOrEqualTo(nVariables)));
				atoms.add(atom);
			}

		}
	}
}
